From 9c15ad745ca398a7da7c3899865cb98f2286faa5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 17 Jun 2006 09:08:14 +0100 Subject: [PATCH] [HVM] ACPI support patch 4 of 4: shutdown. The patch is incorporated from Ben's Virtual Iron's ACPI shutdown patch in changeset 9989:f8d20c3e4225 The patch support guest ACPI Windows shutdown, as well as ACPI guest Linux "halt -p" and "shutdown -h now". Signed-off-by: Ben Thomas Signed-off-by: Winston Wang --- tools/ioemu/hw/piix4acpi.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/ioemu/hw/piix4acpi.c b/tools/ioemu/hw/piix4acpi.c index 655f6c747d..275863a8e7 100644 --- a/tools/ioemu/hw/piix4acpi.c +++ b/tools/ioemu/hw/piix4acpi.c @@ -44,6 +44,10 @@ #define GBL_RLS (1 << 2) #define SLP_EN (1 << 13) +/* Bits of PM1a register define here */ +#define SLP_TYP_MASK 0x1C00 +#define SLP_VAL 0x1C00 + typedef struct AcpiDeviceState AcpiDeviceState; AcpiDeviceState *acpi_device_table; @@ -94,7 +98,7 @@ static int pmtimer_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &s->next_pm_time); qemu_get_timer(f, s->pm_timer); return 0; - + } static inline void acpi_set_irq(PCIAcpiState *s) @@ -277,6 +281,13 @@ static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val) s->pm1_control = (val<<8)||(s->pm1_control); /* printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */ + // Check for power off request + + if ( ( (val & SLP_EN) != 0) && + ( (val & SLP_TYP_MASK) == SLP_VAL) ) { + s->pm1_timer=0x0; //clear ACPI timer + qemu_system_shutdown_request(); + } } static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr) @@ -304,7 +315,6 @@ static void acpiPm1Status_writew(void *opaque, uint32_t addr, uint32_t val) /* printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */ - } static uint32_t acpiPm1Status_readw(void *opaque, uint32_t addr) @@ -345,6 +355,13 @@ static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val) s->pm1_control = val; /* printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */ + // Check for power off request + + if ( ( (val & SLP_EN) != 0) && + ( (val & SLP_TYP_MASK) == SLP_VAL) ) { + qemu_system_shutdown_request(); + } + } static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr) @@ -403,9 +420,9 @@ static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr) static void acpi_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type) { - PCIAcpiState *d = (PCIAcpiState *)pci_dev; - printf("register acpi io \n "); - /*Byte access */ + PCIAcpiState *d = (PCIAcpiState *)pci_dev; + printf("register acpi io \n "); + /*Byte access */ register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d); register_ioport_read(addr, 1, 1, acpiPm1Status_readb, d); register_ioport_write(addr+1, 1, 1, acpiPm1StatusP1_writeb, d); @@ -431,7 +448,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num, register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d); register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d); - /* dword access */ + /* dword access */ register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d); register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d); -- 2.30.2